package com.ljl;

import cn.hutool.core.util.HexUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * @author Administrator
 */
public class Main {

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            throw new IllegalAccessException("参数不正确！用法是 [*.jar/*.exe] [源文件路径] [目标文件路径]");
        }
//        String sourcePath = "C:\\Users\\Administrator\\Documents\\WeChat Files\\wxid_1axrgho31ke722\\FileStorage\\Image\\2022-06";
//        String targetPath = "D:\\Workspace\\Idea\\DatTransfer\\target";
        String sourcePath = args[0];
        String targetPath = args[1];

        File source = new File(sourcePath);
        //检测源文件路径是否合法
        checkFile(source);
        File target = new File(targetPath);
        //检测目标文件路径是否合法
        try {
            checkFile(target);
        }catch (Exception e){
            //如果目标路径不存在，则创建目录
            if (!target.exists()) {
                boolean mkdirs = target.mkdirs();
                if (!mkdirs) {
                    throw new Exception("目标文件夹无法生成");
                }
                targetPath = target.getAbsolutePath();
            }else {
                throw e;
            }
        }
        File[] files = source.listFiles();
        int allFileCount = 0;
        int successFileCount = 0;
        int failFileCount = 0;
        int datFileCount = 0;
        if (files != null) {
            allFileCount = files.length;
            //开始遍历文件夹下的全部文件
            for (File file1 : files) {
                //只筛选dat结尾的文件
                if (file1.getName().toLowerCase(Locale.ROOT).endsWith("dat")) {
                    datFileCount++;
                    try {
                        RandomAccessFile rb = new RandomAccessFile(file1, "r");
                        //读取文件的前两位字节，来判断文件的类型
                        byte[] temp = new byte[3];
                        rb.read(temp);
                        byte xor = 0;
                        //文件类型
                        String suffix = null;
                        Map<String, String> fileTypeMap = FileTypeMap.FILE_TYPE_MAP;
                        Set<Map.Entry<String, String>> entries = fileTypeMap.entrySet();
                        for (Map.Entry<String, String> entry : entries) {
                            String key = entry.getKey();
                            byte[] decodeHex = HexUtil.decodeHex(key);
                            int i1 = temp[0] ^ decodeHex[0];
                            int i2 = temp[1] ^ decodeHex[1];
                            int i3 = temp[2] ^ decodeHex[2];
                            if (i1 == i2 && i2 == i3) {
                                //获取文件类型
                                suffix = entry.getValue();
                                xor = (byte) i1;
                            }
                        }
                        if (suffix != null) {
                            String absolutePath = file1.getParentFile().getAbsolutePath() + File.separator;
                            String fileName = file1.getName().split("\\.")[0];
                            boolean b = transferImage(absolutePath + fileName + ".dat", xor, targetPath + File.separator + fileName + "." + suffix);
                            if (b) {
                                successFileCount++;
                            }else {
                                failFileCount++;
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        System.out.printf("文件总数[%d], dat文件数[%d], 转换成功数[%d], 转换失败数[%d]", allFileCount, datFileCount, successFileCount, failFileCount);
    }

    /**
     * 将dat文件转成相应的文件
     * @param sourceFilePath 源文件路径
     * @param xor 解密值
     * @param targetFilePath 目标文件路径
     * @return 是否成功
     */
    public static boolean transferImage(String sourceFilePath, byte xor,String targetFilePath) {
        RandomAccessFile rb = null;
        FileOutputStream fileOutputStream = null;
        try {
            rb = new RandomAccessFile(sourceFilePath, "r");
            long length = rb.length();
            byte[] res =  new byte[(int) length];
            rb.read(res);
            for (int i = 0; i < res.length; i++) {
                res[i] = (byte) (res[i] ^ xor);
            }
            fileOutputStream = new FileOutputStream(targetFilePath);
            fileOutputStream.write(res);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }finally {
            if (fileOutputStream != null){
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (rb != null){
                try {
                    rb.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void checkFile(File file) throws Exception {
        if (!file.exists()) {
            throw new Exception( "[" + file.getAbsolutePath() + "]路径不存在！");
        }else {
            if (!file.isDirectory()) {
                throw new Exception("[" + file.getAbsolutePath() + "]源文件路径不是一个文件夹！");
            }
        }
    }
}
